package ms.unicorn.modellanguage;

import ms.unicorn.Element;
import ms.unicorn.Relation;
import ms.unicorn.language.languagedef.ConnectionDecorator;
import ms.unicorn.language.languagedef.ConnectionStyleDef;
import ms.unicorn.language.languagedef.DecoratorLocation;
import ms.unicorn.language.languagedef.DecoratorLocatorDef;
import ms.unicorn.language.languagedef.FigureContainer;
import ms.unicorn.language.languagedef.LanguageDefUtil;
import ms.unicorn.language.languagedef.ModuleItem;
import ms.unicorn.language.languagedef.ParameterUtil;
import ms.unicorn.util.ReflectionUtil;
import ms.unicorn.util.TypeConvert;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.draw2d.ConnectionLocator;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.RotatableDecoration;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx;
import org.eclipse.gmf.runtime.notation.Connector;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.swt.graphics.Color;

public class LanguageRelationEditHelperAdvice extends
		LanguageElementEditHelperAdvice {
	public static final String FIGURE_CONNECTION = "connection";
	
	public static final LanguageRelationEditHelperAdvice DefaultInstance = new LanguageRelationEditHelperAdvice();
	
	public LanguageRelationEditHelperAdvice() {
		
	}
	
	@Override
	public View createView(LanguageElement element, IAdaptable semanticAdapter,
			View containerView, String semanticHint, int index,
			boolean persisted, PreferencesHint preferencesHint) {
		Relation reobj = (Relation)getSemanticElement(semanticAdapter);
		View view =  super.createView(element, semanticAdapter, containerView, semanticHint,
				index, persisted, preferencesHint);
		LanguageRelation re = (LanguageRelation) element;
		ConnectionStyleDef cs = re.getConnectionStyle(reobj.getSource(), reobj.getTarget());
		
		if (view instanceof Connector && cs != null) {
			Connector edge = (Connector) view;
			if (cs.isColorSet())
				edge.setLineColor(TypeConvert.toColor(cs.getColor()).handle);
		}
		return view;
	}
	
	@Override
	public FigureContainer createFigure(LanguageElement element,
			Element domainObj, EditPart editpart) {
		FigureContainer figures = super.createFigure(element, domainObj, editpart);
		IFigure connection = figures.getMainFigure();
		
		if (connection instanceof PolylineConnectionEx) {
			LanguageRelation re = (LanguageRelation) element;
			Relation reobj = (Relation) domainObj;
			ConnectionStyleDef cs = re.getConnectionStyle(reobj.getSource(), reobj.getTarget());
			PolylineConnectionEx line = (PolylineConnectionEx) connection;
			if (cs != null) {
				//Connector edge = (Connector) editpart.getModel();
				
				if (cs.isColorSet()) {
					Color lineColor = TypeConvert.toColor(cs.getColor());
					//edge.setLineColor(lineColor.handle);
					line.setForegroundColor(lineColor);
				}
				if (cs.isLineStyleSet()) line.setLineStyle(cs.getStyle().getValue());
				if (cs.isWidthSet()) line.setLineWidth(cs.getWidth());
				// create decorator
				for (ConnectionDecorator decor: cs.getDecorators()) {
					ModuleItem decorDef = LanguageDefUtil.resolveDefinition(decor.getDecorator());
					DecoratorLocation location = ParameterUtil.getConnectorLocation(decor.getParamaters(), DecoratorLocation.TARGET);
					DecoratorLocatorDef locatorDef = ParameterUtil.getConnectorLocator(decor.getParamaters());
					ConnectionLocator locator = null;
					
					if (locatorDef != null) {
						locator = LanguageDefUtil.createFromDefinition(locatorDef, null);
						if (
								locator != null) 
							ReflectionUtil.setPropertyValue(locator, "Connection", connection);
					}
					RotatableDecoration decorObj = LanguageDefUtil.createFromDefinition(decorDef, null);
					if (decorObj != null) {
						if (location == DecoratorLocation.SOURCE)
							if (locator != null) line.setSourceDecoration(decorObj, locator);
							else line.setSourceDecoration(decorObj);
						else 
							if (locator != null) line.setTargetDecoration(decorObj, locator);
							else line.setTargetDecoration(decorObj);
					}
				}
			}
		}
		
		return figures;
	}
	
	public boolean checkRelationConstraints(Element container,
			Relation linkInstance, Element source, Element target) {
		return true;
	}	
}
